home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / network / manageme / tcpdump-.001 / tcpdump-~ / tcpdump-3.0.2-linux / tcpdump-3.0.2 / print-ospf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-15  |  13.6 KB  |  579 lines

  1. /*
  2.  * Copyright (c) 1992, 1993, 1994
  3.  *    The Regents of the University of California.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that: (1) source code distributions
  7.  * retain the above copyright notice and this paragraph in its entirety, (2)
  8.  * distributions including binary code include the above copyright notice and
  9.  * this paragraph in its entirety in the documentation or other materials
  10.  * provided with the distribution, and (3) all advertising materials mentioning
  11.  * features or use of this software display the following acknowledgement:
  12.  * ``This product includes software developed by the University of California,
  13.  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
  14.  * the University nor the names of its contributors may be used to endorse
  15.  * or promote products derived from this software without specific prior
  16.  * written permission.
  17.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  18.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  19.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  20.  *
  21.  * OSPF support contributed by Jeffrey Honig (jch@mitchell.cit.cornell.edu)
  22.  */
  23.  
  24. #ifndef lint
  25. static char rcsid[] =
  26.     "@(#) $Header: print-ospf.c,v 1.12 94/06/14 20:18:46 leres Exp $ (LBL)";
  27. #endif
  28.  
  29. #include <sys/param.h>
  30. #include <sys/time.h>
  31. #include <sys/socket.h>
  32.  
  33. #include <netinet/in.h>
  34. #include <netinet/in_systm.h>
  35. #include <netinet/ip.h>
  36. #include <netinet/ip_var.h>
  37.  
  38. #include <errno.h>
  39. #include <ctype.h>
  40. #include <stdio.h>
  41.  
  42. #include "interface.h"
  43. #include "addrtoname.h"
  44.  
  45. #include "ospf.h"
  46.  
  47. #ifndef    __GNUC__
  48. #define    inline
  49. #endif
  50.  
  51. struct bits {
  52.     u_int32 bit;
  53.     const char *str;
  54. };
  55.  
  56. static const struct bits ospf_option_bits[] = {
  57.     { OSPF_OPTION_T,    "T" },
  58.     { OSPF_OPTION_E,    "E" },
  59.     { OSPF_OPTION_MC,    "MC" },
  60.     { 0,            NULL }
  61. };
  62.  
  63. static const struct bits ospf_rla_flag_bits[] = {
  64.     { RLA_FLAG_B,        "B" },
  65.     { RLA_FLAG_E,        "E" },
  66.     { RLA_FLAG_W1,        "W1" },
  67.     { RLA_FLAG_W2,        "W2" },
  68.     { 0,            NULL }
  69. };
  70.  
  71. static const char *ospf_types[OSPF_TYPE_MAX] = {
  72.   (char *) 0,
  73.   "hello",
  74.   "dd",
  75.   "ls_req",
  76.   "ls_upd",
  77.   "ls_ack"
  78. };
  79.  
  80. static inline void
  81. ospf_print_seqage(register u_int32 seq, register time_t us)
  82. {
  83.     register time_t sec = us % 60;
  84.     register time_t mins = (us / 60) % 60;
  85.     register time_t hour = us/3600;
  86.  
  87.     printf(" S %X age ",
  88.        seq);
  89.     if (hour) {
  90.     printf("%d:%02d:%02d",
  91.            hour,
  92.            mins,
  93.            sec);
  94.     } else if (mins) {
  95.     printf("%d:%02d",
  96.            mins,
  97.            sec);
  98.     } else {
  99.     printf("%d",
  100.            sec);
  101.     }
  102. }
  103.  
  104.  
  105. static inline void
  106. ospf_print_bits(register const struct bits *bp, register u_char options)
  107. {
  108.     char sep = ' ';
  109.  
  110.     do {
  111.     if (options & bp->bit) {
  112.         printf("%c%s",
  113.            sep,
  114.            bp->str);
  115.         sep = '/';
  116.     }
  117.     } while ((++bp)->bit) ;
  118. }
  119.  
  120.  
  121. #define    LS_PRINT(lsp, type) switch (type) { \
  122.     case LS_TYPE_ROUTER: \
  123.     printf(" rtr %s ", ipaddr_string(&lsp->ls_router)); break; \
  124.     case LS_TYPE_NETWORK: \
  125.     printf(" net dr %s if %s", ipaddr_string(&lsp->ls_router), ipaddr_string(&lsp->ls_stateid)); break; \
  126.     case LS_TYPE_SUM_IP: \
  127.     printf(" sum %s abr %s", ipaddr_string(&lsp->ls_stateid), ipaddr_string(&lsp->ls_router)); break; \
  128.     case LS_TYPE_SUM_ABR: \
  129.     printf(" abr %s rtr %s", ipaddr_string(&lsp->ls_router), ipaddr_string(&lsp->ls_stateid)); break; \
  130.     case LS_TYPE_ASE: \
  131.     printf(" ase %s asbr %s", ipaddr_string(&lsp->ls_stateid), ipaddr_string(&lsp->ls_router)); break; \
  132.     case LS_TYPE_GROUP: \
  133.     printf(" group %s rtr %s", ipaddr_string(&lsp->ls_stateid), ipaddr_string(&lsp->ls_router)); break; \
  134.     }
  135.  
  136. static int
  137. ospf_print_lshdr(register const struct lsa_hdr *lshp, const caddr_t end)
  138. {
  139.     if ((caddr_t) (lshp + 1) > end) {
  140.     return 1;
  141.     }
  142.  
  143.     printf(" {");                        /* } (ctags) */
  144.  
  145.     if (!lshp->ls_type || lshp->ls_type >= LS_TYPE_MAX) {
  146.     printf(" ??LS type %d?? }",                /* { (ctags) */
  147.            lshp->ls_type);
  148.     return 1;
  149.     }
  150.  
  151.     ospf_print_bits(ospf_option_bits, lshp->ls_options);
  152.     ospf_print_seqage(ntohl(lshp->ls_seq),
  153.               ntohs(lshp->ls_age));
  154.  
  155.     LS_PRINT(lshp, lshp->ls_type);
  156.  
  157.     return 0;
  158. }
  159.  
  160.  
  161. /*
  162.  * Print a single link state advertisement.  If truncated return 1, else 0.
  163.  */
  164.  
  165. static int
  166. ospf_print_lsa(register const struct lsa *lsap, const caddr_t end)
  167. {
  168.     register const char *ls_end;
  169.     const struct rlalink *rlp;
  170.     const struct tos_metric *tosp;
  171.     const struct in_addr *ap;
  172.     const struct aslametric *almp;
  173.     const struct mcla *mcp;
  174.     const u_int32 *lp;
  175.     int j, k;
  176.  
  177.     if (ospf_print_lshdr(&lsap->ls_hdr, end)) {
  178.     return 1;
  179.     }
  180.  
  181.     ls_end = (caddr_t) lsap + ntohs(lsap->ls_hdr.ls_length);
  182.  
  183.     if (ls_end > end) {
  184.     printf(" }");                        /* { (ctags) */
  185.     return 1;
  186.     }
  187.  
  188.     switch (lsap->ls_hdr.ls_type) {
  189.     case LS_TYPE_ROUTER:
  190.     ospf_print_bits(ospf_rla_flag_bits, lsap->lsa_un.un_rla.rla_flags);
  191.  
  192.     j = ntohs(lsap->lsa_un.un_rla.rla_count);
  193.     rlp = lsap->lsa_un.un_rla.rla_link;
  194.     while (j--) {
  195.         struct rlalink *rln = (struct rlalink *) ((caddr_t) (rlp + 1) + ((rlp->link_toscount) * sizeof (struct tos_metric)));
  196.  
  197.         if ((caddr_t) rln > ls_end) {
  198.         break;
  199.         }
  200.         printf(" {");                    /* } (ctags) */
  201.  
  202.         switch (rlp->link_type) {
  203.         case RLA_TYPE_VIRTUAL:
  204.         printf(" virt");
  205.         /* Fall through */
  206.  
  207.         case RLA_TYPE_ROUTER:
  208.         printf(" nbrid %s if %s",
  209.                ipaddr_string(&rlp->link_id),
  210.                ipaddr_string(&rlp->link_data));
  211.         break;
  212.  
  213.         case RLA_TYPE_TRANSIT:
  214.         printf(" dr %s if %s",
  215.                ipaddr_string(&rlp->link_id),
  216.                ipaddr_string(&rlp->link_data));
  217.         break;
  218.  
  219.         case RLA_TYPE_STUB:
  220.         printf(" net %s mask %s",
  221.                ipaddr_string(&rlp->link_id),
  222.                ipaddr_string(&rlp->link_data));
  223.         break;
  224.  
  225.         default:
  226.         printf(" ??RouterLinksType %d?? }",        /* { (ctags) */
  227.                rlp->link_type);
  228.         return 0;
  229.         }
  230.         printf(" tos 0 metric %d",
  231.            ntohs(rlp->link_tos0metric));
  232.         tosp = (struct tos_metric *) ((sizeof rlp->link_tos0metric) + (caddr_t) rlp);
  233.         for (k = 0; k < rlp->link_toscount; k++, tosp++) {
  234.         printf(" tos %d metric %d",
  235.                ntohs(tosp->tos_type),
  236.                ntohs(tosp->tos_metric));
  237.         }
  238.         printf(" }");                    /* { (ctags) */
  239.         rlp = rln;
  240.     }
  241.     break;
  242.  
  243.     case LS_TYPE_NETWORK:
  244.     printf(" mask %s rtrs",
  245.            ipaddr_string(&lsap->lsa_un.un_nla.nla_mask));
  246.     for (ap = lsap->lsa_un.un_nla.nla_router;
  247.          (caddr_t) (ap + 1) <= ls_end;
  248.          ap++) {
  249.         printf(" %s",
  250.            ipaddr_string(ap));
  251.     }
  252.     break;
  253.  
  254.     case LS_TYPE_SUM_IP:
  255.     printf(" mask %s",
  256.            ipaddr_string(&lsap->lsa_un.un_sla.sla_mask));
  257.     /* Fall through */
  258.  
  259.     case LS_TYPE_SUM_ABR:
  260.  
  261.     for (lp = lsap->lsa_un.un_sla.sla_tosmetric;
  262.          (caddr_t) (lp + 1) <= ls_end;
  263.          lp++) {
  264.         u_int32 ul = ntohl(*lp);
  265.  
  266.         printf(" tos %d metric %d",
  267.            (ul & SLA_MASK_TOS) >> SLA_SHIFT_TOS,
  268.            ul & SLA_MASK_METRIC);
  269.     }
  270.     break;
  271.  
  272.     case LS_TYPE_ASE:
  273.     printf(" mask %s",
  274.            ipaddr_string(&lsap->lsa_un.un_asla.asla_mask));
  275.  
  276.     for (almp = lsap->lsa_un.un_asla.asla_metric;
  277.          (caddr_t) (almp + 1) <= ls_end;
  278.          almp++) {
  279.         u_int32 ul = ntohl(almp->asla_tosmetric);
  280.  
  281.         printf(" type %d tos %d metric %d",
  282.            (ul & ASLA_FLAG_EXTERNAL) ? 2 : 1,
  283.            (ul & ASLA_MASK_TOS) >> ASLA_SHIFT_TOS,
  284.            (ul & ASLA_MASK_METRIC));
  285.         if (almp->asla_forward.s_addr) {
  286.         printf(" forward %s",
  287.                ipaddr_string(&almp->asla_forward));
  288.         }
  289.         if (almp->asla_tag.s_addr) {
  290.         printf(" tag %s",
  291.                ipaddr_string(&almp->asla_tag));
  292.         }
  293.     }
  294.     break;
  295.  
  296.     case LS_TYPE_GROUP:
  297.     /* Multicast extensions as of 23 July 1991 */
  298.     for (mcp = lsap->lsa_un.un_mcla;
  299.          (caddr_t) (mcp + 1) <= ls_end;
  300.          mcp++) {
  301.         switch (ntohl(mcp->mcla_vtype)) {
  302.         case MCLA_VERTEX_ROUTER:
  303.         printf(" rtr rtrid %s",
  304.                ipaddr_string(&mcp->mcla_vid));
  305.         break;
  306.  
  307.         case MCLA_VERTEX_NETWORK:
  308.         printf(" net dr %s",
  309.                ipaddr_string(&mcp->mcla_vid));
  310.         break;
  311.  
  312.         default:
  313.         printf(" ??VertexType %d??",
  314.                ntohl(mcp->mcla_vtype));
  315.         break;
  316.         }
  317.     }
  318.     }
  319.  
  320.     printf(" }");                        /* { (ctags) */
  321.     return 0;
  322. }
  323.  
  324.  
  325. void
  326. ospf_print(register const u_char *bp, register int length,
  327.        register const u_char *bp2)
  328. {
  329.     register const struct ospfhdr *op;
  330.     register const struct ip *ip;
  331.     register const caddr_t end = (caddr_t)snapend;
  332.     register const struct lsa *lsap;
  333.     register const struct lsa_hdr *lshp;
  334.     char sep;
  335.     int i, j;
  336.     const struct in_addr *ap;
  337.     const struct lsr *lsrp;
  338.  
  339.     op = (struct ospfhdr *)bp;
  340.     ip = (struct ip  *)bp2;
  341.     /* Print the source and destination address    */
  342.     (void) printf("%s > %s:",
  343.           ipaddr_string(&ip->ip_src),
  344.           ipaddr_string(&ip->ip_dst));
  345.  
  346.     if ((caddr_t) (&op->ospf_len + 1) > end) {
  347.     goto trunc_test;
  348.     }
  349.  
  350.     /* If the type is valid translate it, or just print the type */
  351.     /* value.  If it's not valid, say so and return */
  352.     if (op->ospf_type || op->ospf_type < OSPF_TYPE_MAX) {
  353.     printf(" OSPFv%d-%s %d:",
  354.            op->ospf_version,
  355.            ospf_types[op->ospf_type],
  356.            length);
  357.     } else {
  358.     printf(" ospf-v%d-??type %d?? %d:",
  359.            op->ospf_version,
  360.            op->ospf_type,
  361.            length);
  362.     return;
  363.     }
  364.  
  365.     if (length != ntohs(op->ospf_len)) {
  366.     printf(" ??len %d??",
  367.            ntohs(op->ospf_len));
  368.     goto trunc_test;
  369.     }
  370.  
  371.     if ((caddr_t) (&op->ospf_routerid + 1) > end) {
  372.     goto trunc_test;
  373.     }
  374.  
  375.     /* Print the routerid if it is not the same as the source */
  376.     if (ip->ip_src.s_addr != op->ospf_routerid.s_addr) {
  377.     printf(" rtrid %s",
  378.            ipaddr_string(&op->ospf_routerid));
  379.     }
  380.  
  381.     if ((caddr_t) (&op->ospf_areaid + 1) > end) {
  382.     goto trunc_test;
  383.     }
  384.  
  385.     if (op->ospf_areaid.s_addr) {
  386.     printf(" area %s",
  387.            ipaddr_string(&op->ospf_areaid));
  388.     } else {
  389.     printf(" backbone");
  390.     }
  391.  
  392.     if ((caddr_t) (op->ospf_authdata + OSPF_AUTH_SIZE) > end) {
  393.     goto trunc_test;
  394.     }
  395.  
  396.     if (vflag) {
  397.     /* Print authentication data (should we really do this?) */
  398.     switch (ntohs(op->ospf_authtype)) {
  399.     case OSPF_AUTH_NONE:
  400.         break;
  401.  
  402.     case OSPF_AUTH_SIMPLE:
  403.         printf(" auth ");
  404.         j = 0;
  405.         for (i = 0; i < sizeof (op->ospf_authdata); i++) {
  406.         if (!isprint(op->ospf_authdata[i])) {
  407.             j = 1;
  408.             break;
  409.         }
  410.         }
  411.         if (j) {
  412.         /* Print the auth-data as a string of octets */
  413.         printf("%s.%s",
  414.                ipaddr_string((struct in_addr *) op->ospf_authdata),
  415.                ipaddr_string((struct in_addr *) &op->ospf_authdata[sizeof (struct in_addr)]));
  416.         } else {
  417.         /* Print the auth-data as a text string */
  418.         printf("'%.8s'",
  419.                op->ospf_authdata);
  420.         }
  421.         break;
  422.  
  423.     default:
  424.         printf(" ??authtype-%d??",
  425.            ntohs(op->ospf_authtype));
  426.         return;
  427.     }
  428.     }
  429.  
  430.  
  431.     /* Do rest according to version.    */
  432.     switch (op->ospf_version) {
  433.     case 2:
  434.         /* ospf version 2    */
  435.     switch (op->ospf_type) {
  436.     case OSPF_TYPE_UMD:        /* Rob Coltun's special monitoring packets; do nothing    */
  437.         break;
  438.  
  439.     case OSPF_TYPE_HELLO:
  440.         if ((caddr_t) (&op->ospf_hello.hello_deadint + 1) > end) {
  441.         break;
  442.         }
  443.         if (vflag) {
  444.         ospf_print_bits(ospf_option_bits, op->ospf_hello.hello_options);
  445.         printf(" mask %s int %d pri %d dead %d",
  446.                ipaddr_string(&op->ospf_hello.hello_mask),
  447.                ntohs(op->ospf_hello.hello_helloint),
  448.                op->ospf_hello.hello_priority,
  449.                ntohl(op->ospf_hello.hello_deadint));
  450.         }
  451.  
  452.         if ((caddr_t) (&op->ospf_hello.hello_dr + 1) > end) {
  453.         break;
  454.         }
  455.         if (op->ospf_hello.hello_dr.s_addr) {
  456.         printf(" dr %s",
  457.                ipaddr_string(&op->ospf_hello.hello_dr));
  458.         }
  459.  
  460.         if ((caddr_t) (&op->ospf_hello.hello_bdr + 1) > end) {
  461.         break;
  462.         }
  463.         if (op->ospf_hello.hello_bdr.s_addr) {
  464.         printf(" bdr %s",
  465.                ipaddr_string(&op->ospf_hello.hello_bdr));
  466.         }
  467.  
  468.         if (vflag) {
  469.         if ((caddr_t) (op->ospf_hello.hello_neighbor + 1) > end) {
  470.             break;
  471.         }
  472.         printf(" nbrs");
  473.         for (ap = op->ospf_hello.hello_neighbor;
  474.              (caddr_t) (ap + 1) <= end;
  475.              ap++) {
  476.             printf(" %s",
  477.                ipaddr_string(ap));
  478.         }
  479.         }
  480.         break;            /*  HELLO    */
  481.  
  482.     case OSPF_TYPE_DB:
  483.         if ((caddr_t) (&op->ospf_db.db_seq + 1) > end) {
  484.         break;
  485.         }
  486.         ospf_print_bits(ospf_option_bits, op->ospf_db.db_options);
  487.         sep = ' ';
  488.         if (op->ospf_db.db_flags & OSPF_DB_INIT) {
  489.         printf("%cI",
  490.                sep);
  491.         sep = '/';
  492.         }
  493.         if (op->ospf_db.db_flags & OSPF_DB_MORE) {
  494.         printf("%cM",
  495.                sep);
  496.         sep = '/';
  497.         }
  498.         if (op->ospf_db.db_flags & OSPF_DB_MASTER) {
  499.         printf("%cMS",
  500.                sep);
  501.         sep = '/';
  502.         }
  503.         printf(" S %X",
  504.            ntohl(op->ospf_db.db_seq));
  505.  
  506.         if (vflag) {
  507.         /* Print all the LS adv's */
  508.         lshp = op->ospf_db.db_lshdr;
  509.  
  510.         while (!ospf_print_lshdr(lshp, end)) {
  511.             printf(" }");                /* { (ctags) */
  512.             lshp++;
  513.         }
  514.         }
  515.         break;
  516.  
  517.     case OSPF_TYPE_LSR:
  518.         if (vflag) {
  519.         for (lsrp = op->ospf_lsr; (caddr_t) (lsrp+1) <= end; lsrp++) {
  520.             int32 type;
  521.  
  522.             if ((caddr_t) (lsrp + 1) > end) {
  523.             break;
  524.             }
  525.  
  526.             printf(" {");                /* } (ctags) */
  527.             if (!(type = lsrp->ls_type) || type >= LS_TYPE_MAX) {
  528.             printf(" ??LinkStateType %d }",        /* { (ctags) */
  529.                    type);
  530.             printf(" }");                /* { (ctags) */
  531.             break;
  532.             }
  533.  
  534.             LS_PRINT(lsrp, type);
  535.             printf(" }");                /* { (ctags) */
  536.         }
  537.         }
  538.         break;
  539.  
  540.     case OSPF_TYPE_LSU:
  541.         if (vflag) {
  542.         lsap = op->ospf_lsu.lsu_lsa;
  543.         i = ntohl(op->ospf_lsu.lsu_count);
  544.  
  545.         while (i-- &&
  546.                !ospf_print_lsa(lsap, end)) {
  547.             lsap = (struct lsa *) ((caddr_t) lsap + ntohs(lsap->ls_hdr.ls_length));
  548.         }
  549.         }
  550.         break;
  551.  
  552.  
  553.     case OSPF_TYPE_LSA:
  554.         if (vflag) {
  555.         lshp = op->ospf_lsa.lsa_lshdr;
  556.  
  557.         while (!ospf_print_lshdr(lshp, end)) {
  558.             printf(" }");                /* { (ctags) */
  559.             lshp++;
  560.         }
  561.         break;
  562.         }
  563.     }            /* end switch on v2 packet type    */
  564.     break;
  565.  
  566.     default:
  567.     printf(" ospf [version %d]",
  568.            op->ospf_version);
  569.     break;
  570.     }                    /* end switch on version    */
  571.  
  572.   trunc_test:
  573.     if ((snapend - bp) < length) {
  574.     printf(" [|]");
  575.     }
  576.  
  577.     return;                /* from ospf_print    */
  578. }
  579.